﻿using GMS.Client.Core;
using GMS.Client.Model;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Timers;

namespace GMS.Client.Domain
{
    /// <summary>
    /// 监视器领域服务
    /// </summary>
    public class MonitorService
    {
        /// <summary>
        /// 用户信息
        /// </summary>
        private GameInfo gameInfo { get; set; }

        /// <summary>
        /// 游戏服务
        /// </summary>
        private GameService iGame { get; set; }

        /// <summary>
        /// 战斗信息列表
        /// </summary>
        private List<BattleInfo> BattleInfoList { get; set; }

        /// <summary>
        /// 拾取信息哈希
        /// </summary>
        private string LootHash { get; set; }

        /// <summary>
        /// 战斗信息计时器
        /// </summary>
        private Timer BattleInfoTimer { get; set; }

        /// <summary>
        /// 拾取计时器
        /// </summary>
        private Timer LootTimer { get; set; }

        /// <summary>
        /// 当前战斗信息
        /// </summary>
        public BattleInfo CurrentBattleInfo { get; set; }

        private Window TNT { get; set; }

        public Action ReStart { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="battleDataControlList"></param>
        /// <param name="gameInfo"></param>
        public MonitorService(GameInfo gameInfo)
        {
            this.gameInfo = gameInfo;
            this.iGame = new GameService(gameInfo);
            iGame.Clear();
            iGame.SetGameConfig();
            TNT = iGame.Start();
            iGame.Run(iGame.Login(TNT));

            BattleInfoTimer = new Timer(gameInfo.BattleInfoTimerInterval / 10);
            BattleInfoTimer.Elapsed += BattleInfoTimer_Elapsed;

            LootTimer = new Timer(gameInfo.VendorInfoTimerInterval);
            LootTimer.Elapsed += LootTimer_Elapsed;
        }

        /// <summary>
        /// 拾取计时器事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LootTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(LootHash))
            {
                LootHash = ReadLootLog();
                Console.WriteLine(LootHash);
                LootTimer.Start();
            }
            else
            {
                var lootHash = ReadLootLog();
                Console.WriteLine(lootHash);
                if (LootHash.Equals(lootHash))
                {
                    LootHash = string.Empty;
                    StopMonitor();

                    Console.WriteLine("{0}没有拾取装备，重启{1}...", DateTime.Now, gameInfo.TitleName);
                    ReStart.Invoke();
                }
                else
                {
                    LootHash = lootHash;
                    LootTimer.Start();
                }
            }
        }

        /// <summary>
        /// 停止所有计时器
        /// </summary>
        public void StopMonitor()
        {
            BattleInfoTimer.Stop();
            LootTimer.Stop();
        }

        /// <summary>
        /// 启动监视器
        /// </summary>
        public void StartMonitor()
        {
            BattleInfoTimer.Start();
            LootTimer.Start();
        }

        /// <summary>
        /// 战斗信息计时器事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BattleInfoTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (BattleInfoList == null)
            {
                Console.WriteLine("{0}金币统计列表为空{1}...", DateTime.Now, gameInfo.TitleName);
                BattleInfoList = new List<BattleInfo>();
            }

            var battleInfo = new BattleInfo();

            if (!iGame.FindWindow(TNT.Handle))
            {
                Console.WriteLine("{0}TNT窗口已经更新{1}...", DateTime.Now, gameInfo.TitleName);
                TNT = iGame.Init(TNT);
            }

            battleInfo.DeathTimes = (TNT.Controls.Single(c => c.CustomControlNameType == CustomControlNameType.Txt_DeathTimes) as TextBox).GetValue<int>();
            battleInfo.Exp = (TNT.Controls.Single(c => c.CustomControlNameType == CustomControlNameType.Txt_Exp) as TextBox).GetValue<decimal>();
            battleInfo.LootGold = (TNT.Controls.Single(c => c.CustomControlNameType == CustomControlNameType.Txt_LootGold) as TextBox).GetValue<int>();

            CurrentBattleInfo = battleInfo;

            Console.WriteLine("{0}触发拾取金币事件{1} 死亡次数{2} 经验{3} 拾取金币{4}...", DateTime.Now, gameInfo.TitleName, battleInfo.DeathTimes, battleInfo.Exp, battleInfo.LootGold);

            if (BattleInfoList.Count < 10)
            {
                BattleInfoList.Add(battleInfo);
                BattleInfoTimer.Start();
            }
            else
            {
                var firstBattleInfo = BattleInfoList[0];
                if (CurrentBattleInfo.LootGold == firstBattleInfo.LootGold)
                {
                    StopMonitor();
                    Console.WriteLine("{0}没有拾取金币，重启{1}...", DateTime.Now, gameInfo.TitleName);
                    ReStart.Invoke();
                }
                else
                {
                    BattleInfoList.RemoveAt(0);
                    BattleInfoList.Add(CurrentBattleInfo);
                    BattleInfoTimer.Start();
                }
            }
        }

        /// <summary>
        /// 读取拾取日志
        /// </summary>
        /// <returns></returns>
        private string ReadLootLog()
        {
            var hashString = string.Empty;
            var fileName = gameInfo.WorkingDirectory + string.Format(@"\Log\{0}-Log-Loot.txt", DateTime.Now.Date.ToString("MMddyyyy"));
            if (File.Exists(fileName))
            {
                var fileInfo = new FileInfo(fileName);
                var canRead = false;
                while (!canRead)
                {
                    using (var streamReader = fileInfo.OpenText())
                    {
                        hashString = streamReader.ReadToEnd();
                        streamReader.Close();
                        streamReader.Dispose();
                        canRead = true;
                    }
                }
            }
            using (var md5 = new MD5CryptoServiceProvider())
            {
                var bytes = Encoding.Default.GetBytes(hashString);
                var result = md5.ComputeHash(bytes);
                var md5Result = BitConverter.ToString(result).Replace("-", "");
                md5.Dispose();
                return md5Result;
            }
        }
    }
}
